package com.tian.auto.export;

import com.alibaba.excel.EasyExcel;
import com.tian.auto.Constants;
import com.tian.auto.Log;
import com.tian.auto.StringUtils;
import com.tian.auto.info.PathBean;
import com.tian.auto.info.ResData;
import com.tian.auto.parse.PathParseProcessor;

import org.dom4j.Attribute;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;

import java.io.File;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.Iterator;

import static com.tian.auto.Constants.PROJECT_STRING_PATH_MAP;

/**
 * Description: 将本地项目中定义在xml中的string，string-array导出的工具
 * Author:  tianjinyong
 * Date:    2019-10-29 17:00
 */
public class ExportHelper {

    private static volatile ExportHelper mExportHelper;

    /**
     * 在doc目录下生成xlsx文件的前缀
     */
    private String docNamePrefix = "create";

    private String rootPath;


    private ExportHelper() {
    }

    public static ExportHelper create(String docNamePrefix, String localRootPath) {
        if (mExportHelper == null) {
            synchronized (ExportHelper.class) {
                if (mExportHelper == null) {
                    mExportHelper = new ExportHelper();
                }
            }
        }

        mExportHelper.docNamePrefix = docNamePrefix;
        mExportHelper.rootPath = localRootPath;
        return mExportHelper;
    }


    /**
     * 将工程中的 string数据，导出为excel表
     */
    public void exportValuesToExcel() throws DocumentException {
        PathParseProcessor.initProjectStringPathMap(rootPath);

        //结构集合
        ArrayList<ResData> resDatas = new ArrayList<>();

        /*
         *遍历 values下目录 获取values环境的 所有string键或者string-array键
         *
         */
        for (String key : PROJECT_STRING_PATH_MAP.keySet()) {
            if (key.endsWith("values")) {
                PathBean pathBean = PROJECT_STRING_PATH_MAP.get(key);

                if (pathBean.getStringXmlFiles() == null || pathBean.getStringXmlFiles().isEmpty())
                    continue;

                //遍历xml文件中的string键和string-array键值对
                for (String filePath : pathBean.getStringXmlFiles()) {
                    if (StringUtils.isEmpty(filePath))
                        continue;

                    SAXReader reader = new SAXReader();
                    Document document = reader.read(new File(filePath));
                    //获取根节点
                    Element rootElement = document.getRootElement();
                    //获取根节点下,名为string的子节点迭代器
                    Iterator<Element> stringItem = rootElement.elementIterator(Constants.ElementValues.ELEMENT_STRING);

                    while (stringItem.hasNext()) {
                        Element element = stringItem.next();

                        if (element.attributes() == null || element.attributes().isEmpty())
                            continue;

                        String keyName = "";

                        //获取定义在xml中string字符串 的键名(取"name"键)
                        for (Attribute attribute : element.attributes()) {
                            if ("name".equals(attribute.getName())) {
                                keyName = attribute.getValue();
                            }
                        }

                        if (StringUtils.isEmpty(keyName))
                            continue;

                        //生成ResData
                        ResData res = new ResData();
                        res.setPlatform("android");
                        res.setPathInfo(pathBean.getModuleName() + "*" + keyName);
                        //设置cnValue
                        res.setCnValue(element.getStringValue());
                        //设置enValue
                        res.setEnValue(getElementValueByKey(new File(filePath.replace("values/", "values-en/")), keyName));
                        //设置zhr-TW Value
                        res.setZhrTwValue(getElementValueByKey(new File(filePath.replace("values/", "values-zh-rTW/")), keyName));
                        //设置th-rTH Value
                        res.setThrTHValues(getElementValueByKey(new File(filePath.replace("values/", "values-th-rTH/")), keyName));

                        resDatas.add(res);

                        Log.info("tt", res.toString());
                    }

                    //获取根节点下,名为string-array的子节点迭代器
                    Iterator<Element> stringArrayItem = rootElement.elementIterator(Constants.ElementValues.ELEMENT_STRING_ARRAY);

                    while (stringArrayItem.hasNext()) {
                        Element element = stringArrayItem.next();

                        if (element.attributes() == null || element.attributes().isEmpty())
                            continue;

                        String keyName = "";

                        //获取定义在xml中stringArray字符串 的键名(取"name"键)
                        for (Attribute attribute : element.attributes()) {
                            if ("name".equals(attribute.getName())) {
                                keyName = attribute.getValue();
                            }
                        }

                        if (StringUtils.isEmpty(keyName))
                            continue;

                        //遍历string-array
                        Iterator<Element> iterator = element.elementIterator(Constants.ElementValues.ELEMENT_ITEM);
                        int currentIndex = 0;

                        while (iterator.hasNext()) {
                            Element itemChild = iterator.next();
                            //生成ResData
                            ResData res = new ResData();
                            res.setPlatform("android");
                            res.setPathInfo(pathBean.getModuleName() + "*" + keyName + "^item" + currentIndex);

                            res.setCnValue(itemChild.getStringValue());
                            res.setEnValue(getStringArrayValue(new File(filePath.replace("values/", "values-en/")), keyName, currentIndex));
                            res.setZhrTwValue(getStringArrayValue(new File(filePath.replace("values/", "values-zh-rTW/")), keyName, currentIndex));
                            //设置th-rTH Value
                            res.setThrTHValues(getStringArrayValue(new File(filePath.replace("values/", "values-th-rTH/")), keyName, currentIndex));
                            resDatas.add(res);
                            Log.info("tt", res.toString());

                            currentIndex++;
                        }
                    }
                }
            }
        }

        Log.info("tt-src", resDatas.size() + "");

        //以"calm-app-hy*,calm-app-beauty*,retail*" 不生成表，存档的时候这个方法需要掉，不存档的时候不用调用
        removeTagPath(resDatas);
        Log.info("tt", resDatas.size() + "");
        //最终生成的excel 文件
        String docFileName = "/Users/tianjinyong/Desktop/work/international/doc/" + docNamePrefix + new SimpleDateFormat("yyyy-MM-dd-HH-mm").format(new Date()) + ".xlsx";
        EasyExcel.write(docFileName, ResData.class)
                .registerWriteHandler(MarkNullCellWriteHandler.create(resDatas))
                .sheet("模板")
                .doWrite(resDatas);
    }

    /**
     * 获取 keyName 对应的 定义在xml中的string资源的 值
     *
     * @param file
     * @param keyName
     * @return
     */
    private String getElementValueByKey(File file, String keyName) throws DocumentException {
        if (!file.exists())
            return "";

        String result = "";

        SAXReader reader = new SAXReader();
        Document document = reader.read(file);
        //获取根节点
        Element rootElement = document.getRootElement();
        //获取根节点下,名为string的子节点迭代器
        Iterator<Element> stringItem = rootElement.elementIterator(Constants.ElementValues.ELEMENT_STRING);

        while (stringItem.hasNext()) {
            Element element = stringItem.next();
            //获取定义在xml中string字符串 的键名(取"name"键)
            for (Attribute attribute : element.attributes()) {
                if ("name".equals(attribute.getName()) && keyName.equals(attribute.getValue())) {
                    result = element.getStringValue();
                    break;
                }
            }
        }

        return result;
    }

    /**
     * 获取keyName 对应的 定义在xml中的string-array 中的 index坐标的值
     *
     * @param file
     * @param keyName
     * @param arrayIndex
     * @return
     * @throws DocumentException
     */
    private String getStringArrayValue(File file, String keyName, int arrayIndex) throws DocumentException {
        if (!file.exists())
            return "";

        SAXReader reader = new SAXReader();
        Document document = reader.read(file);
        //获取根节点
        Element rootElement = document.getRootElement();
        //获取根节点下,名为string的子节点迭代器
        Iterator<Element> stringArrayItem = rootElement.elementIterator(Constants.ElementValues.ELEMENT_STRING_ARRAY);

        while (stringArrayItem.hasNext()) {
            Element element = stringArrayItem.next();
            //获取定义在xml中string-array 的键名(取"name"属性)
            for (Attribute attribute : element.attributes()) {
                if ("name".equals(attribute.getName()) && keyName.equals(attribute.getValue())) {

                    //遍历string-array
                    Iterator<Element> iterator = element.elementIterator(Constants.ElementValues.ELEMENT_ITEM);
                    int currentIndex = 0;

                    while (iterator.hasNext()) {
                        Element itemChild = iterator.next();

                        if (currentIndex == arrayIndex) {
                            return itemChild.getStringValue();
                        }
                        currentIndex++;
                    }

                    break;
                }
            }
        }

        return "";
    }

    /**
     * 以"calm-app-hy*,calm-app-beauty*,retail*" 不生成表
     *
     * @param resDatas
     */
    public void removeTagPath(ArrayList<ResData> resDatas) {
        Iterator<ResData> iterator = resDatas.iterator();

        while (iterator.hasNext()) {
            ResData item = iterator.next();

            if (item.getPathInfo() == null || item.getPathInfo().length() == 0)
                continue;

            if (item.getPathInfo().startsWith("calm-app-hy*")
                    || item.getPathInfo().startsWith("calm-app-beauty*")
                    || item.getPathInfo().startsWith("retail*")
                    || item.getPathInfo().startsWith("retail-app-bakery*")
                    || item.getPathInfo().startsWith("retail-app-cvs*")
                    || item.getPathInfo().startsWith("retail-app-fresh*")
                    || item.getPathInfo().startsWith("retail-app-retail*")
            ) {
                iterator.remove();
            }
        }
    }

}
